package com.lk.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.lk.basic.util.AjaxResult;
import com.lk.basic.util.HttpClientUtils;
import com.lk.basic.util.MD5Utils;
import com.lk.basic.util.WxConstants;
import com.lk.user.domain.Logininfo;
import com.lk.user.domain.Wxuser;
import com.lk.user.dto.AccountLoginDTO;
import com.lk.user.dto.GmmLoginDTO;
import com.lk.user.dto.YzmLoginDTO;
import com.lk.user.mapper.LogininfoMapper;
import com.lk.user.mapper.WxuserMapper;
import com.lk.user.service.ILogininfoService;
import com.lk.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lk
 * @since 2022-11-15
 */
@Service
public class LogininfoServiceImpl extends BaseServiceImpl<Logininfo> implements ILogininfoService {

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private WxuserMapper wxuserMapper;


    @Override
    public AjaxResult accountLogin(AccountLoginDTO dto) {
        String username = dto.getUsername();
        String password = dto.getPassword();
        Integer type = dto.getType();
        //校验参数
        if (StringUtils.isEmpty(username)||StringUtils.isEmpty(password)&&type==null){
            throw new RuntimeException("参数错误，请核实");
        }
        Logininfo logininfo = logininfoMapper.findLogininfoByUsername(dto);
        if(Objects.isNull(logininfo)){
            //throw new RuntimeException("用户名或密码错误!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("用户名或密码错误!请检查后重新登录!");
        }
        if(logininfo.getDisable() == 0){
            //throw new RuntimeException("该用户已被禁用!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("该用户已被禁用!请检查后重新登录!");
        }
        //校验密码
        password=MD5Utils.encrypByMd5("123"+logininfo.getSalt()+"123"+password);
        if (!password.equals(logininfo.getPassword())){
            throw new RuntimeException("用户名或密码错误");
        }

        return loginSuccessHandle(logininfo);


    }

    private AjaxResult loginSuccessHandle(Logininfo logininfo) {
        //登录成功，讲token存入redis
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, logininfo,30, TimeUnit.MINUTES);

        //将信息返回前端
        Map<String,Object> result=new HashMap<>();
        result.put("token",token);
        logininfo.setPassword("");//将密码设置为空
        logininfo.setSalt("");//将盐值设置为空
        result.put("logininfo", logininfo);
        return AjaxResult.me().setResult(result);
    }

    @Override
    public AjaxResult wechatLogin(Map<String, Object> map) {
        String code=(String) map.get("code");
        //通过code获取accessToken和openid
        //GET_ACK_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        //替换上面地址中的APPID，CODE，SECRET
        //grant_type=authorization_code这个格式是固定的，不需要替换
        String accessTokenUrl=WxConstants.GET_ACK_URL
                .replace("APPID",WxConstants.APPID)
                .replace("CODE",code)
                .replace("SECRET",WxConstants.SECRET);

        String resultStr = HttpClientUtils.httpGet(accessTokenUrl);
        //将字符转为json对象
        JSONObject resultObj = JSONObject.parseObject(resultStr);
        String access_token = resultObj.getString("access_token");
        String openid = resultObj.getString("openid");

        System.out.println(openid);
        Wxuser wxuser=wxuserMapper.loadByOpenId(openid);
        //根据openid判断用户是否存在
        if (Objects.nonNull(wxuser)){
            //存在，进行免密登录
            Long wxuserId = wxuser.getId();
            Logininfo logininfo=logininfoMapper.selByIdUserId(wxuserId);
            return loginSuccessHandle(logininfo);
        }else {
            //不存在，携带access_token与openid进入绑定页面
            //因为是前后端分离项目，后端无非直接跳转，所以只能给前端返回数据
            Map<String,Object> resultMap=new HashMap<>();
            resultMap.put("access_token",access_token);
            resultMap.put("openid",openid);
            return AjaxResult.me().setSuccess(false).setMessage("toBind").setResult(resultMap);
        }
    }

    @Override
    public AjaxResult yzmLogin(YzmLoginDTO dto) {
        String username = dto.getUsername();
        String verify = dto.getVerify();
        if (StringUtils.isEmpty(username)){
            throw new RuntimeException("手机号不能为空");
        }
        if (StringUtils.isEmpty(verify)){
            throw new RuntimeException("验证码不能为空");
        }
        //校验手机验证码是否正确
        String smsCodeStr=(String)redisTemplate.opsForValue().get("login_sms_code_"+username);
        if (StringUtils.isEmpty(smsCodeStr)){
            return AjaxResult.me().setSuccess(false).setMessage("验证码过期");
        }
        String smsCodeFromRedis = smsCodeStr.split(":")[0];
        if (!verify.equals(smsCodeFromRedis)){
            return AjaxResult.me().setSuccess(false).setMessage("验证码错误");
        }
        Logininfo logininfo = logininfoMapper.findLogininfoByPhone(dto);
        if(Objects.isNull(logininfo)){
            //throw new RuntimeException("用户名或密码错误!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("手机号未注册!");
        }
        if(logininfo.getDisable() == 0){
            //throw new RuntimeException("该用户已被禁用!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("该用户已被禁用!请检查后重新登录!");
        }
        return loginSuccessHandle(logininfo);

    }

    @Override
    public AjaxResult gmmLogin(GmmLoginDTO dto) {
        String username = dto.getUsername();
        String verify = dto.getVerify();
        String password = dto.getPassword();
        String confirmpassword = dto.getConfirmpassword();
        if (StringUtils.isEmpty(username)||StringUtils.isEmpty(verify)||StringUtils.isEmpty(password)||StringUtils.isEmpty(confirmpassword)){
            return AjaxResult.me().setSuccess(false).setMessage("参数不能为空");
        }
        //校验手机验证码是否正确
        String smsCodeStr=(String)redisTemplate.opsForValue().get("login_sms_code_"+username);
        if (StringUtils.isEmpty(smsCodeStr)){
            return AjaxResult.me().setSuccess(false).setMessage("验证码过期");
        }
        String smsCodeFromRedis = smsCodeStr.split(":")[0];
        if (!verify.equals(smsCodeFromRedis)){
            return AjaxResult.me().setSuccess(false).setMessage("验证码错误");
        }
        Logininfo logininfo = logininfoMapper.findLogininfoByUsernameGmm(dto);
        if(Objects.isNull(logininfo)){
            //throw new RuntimeException("用户名或密码错误!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("用户不存在!");
        }
        if(logininfo.getDisable() == 0){
            //throw new RuntimeException("该用户已被禁用!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("该用户已被禁用!请检查后重新登录!");
        }
        return loginSuccessHandle(logininfo);

    }
}
